package com.hhsjtest.composiable.logtest

import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.widget.FrameLayout
import android.view.ViewGroup

class LogFrameLayout : FrameLayout {
    private var mLogView: LogView? = null

    private var showTouchTarget = false;

    fun setLogView(mLogView: LogView?) {
        this.mLogView = mLogView
    }

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        val action = ev.action
        if (action == MotionEvent.ACTION_MOVE) {
            Log.e("HHSJ", "--------父视图 intercept 进入 move 判断")
            if (mLogView?.intercept == true) {
                val viewGroupClass = ViewGroup::class.java
                try {
                    val field = viewGroupClass.getDeclaredField("mFirstTouchTarget")
                    field.isAccessible = true
                    val firstTouchTarget = field[this]
                    if (firstTouchTarget == null) {
                        Log.e("HHSJ", "--------mFirstTouchTarget = null")
                    } else {
                        Log.e("HHSJ", "--------mFirstTouchTarget = " + firstTouchTarget.hashCode())
                        val field1 = firstTouchTarget.javaClass.getField("child")
                        field1.isAccessible = true
                        val child = field1[firstTouchTarget]
                        if (child != null) {
                            Log.e("HHSJ", "--------TouchTarget child " + child.hashCode())
                            Log.e("HHSJ", "--------FrameLayout child " + getChildAt(0).hashCode())
                        } else {
                            Log.e("HHSJ", "--------TouchTarget child = null")
                        }
                    }
                } catch (e: NoSuchFieldException) {
                    e.printStackTrace()
                } catch (e: IllegalAccessException) {
                    e.printStackTrace()
                }
                Log.e("HHSJ", "--------move 被 FrameLayout 拦截了")
                return true
            }
        }
        return super.onInterceptTouchEvent(ev)
    }

    override fun onTouchEvent(ev: MotionEvent): Boolean {
        val action = ev.action
        if (action == MotionEvent.ACTION_MOVE) {
            Log.e("HHSJ", "--------父视图 touch move")
            Log.e("HHSJ", "--------父视图 touch 进入 move 判断")
            if (mLogView?.intercept == true) {
                printTarget("--------", "touch move", "")
                Log.e("HHSJ", "--------父视图 touch move 设置返回 true")
                return true
            }
        }
        if (action == MotionEvent.ACTION_DOWN) {
            Log.e("HHSJ", "--------父视图 touch down")
        }
        if (action == MotionEvent.ACTION_CANCEL) {
            Log.e("HHSJ", "--------父视图 touch cancel===")
        }
        if (action == MotionEvent.ACTION_UP) {
            Log.e("HHSJ", "--------父视图 touch up===")
        }
        return super.onTouchEvent(ev)
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        val action = ev.action
        Log.e("HHSJ", "-------------------------新事件")
        if (action == MotionEvent.ACTION_DOWN) {
            Log.e("HHSJ", "--------父视图 dispatch down")
            val dispatch = super.dispatchTouchEvent(ev)
            printTarget("--------", "dispatch down", "后")
            return dispatch;
        }
        if (action == MotionEvent.ACTION_MOVE) {
            Log.e("HHSJ", "--------父视图 dispatch move")
            printTarget("--------", "dispatch move", "前")
            val dispatch = super.dispatchTouchEvent(ev)
            Log.e("HHSJ", "--------父视图 dispatch move result: $dispatch")
            printTarget("--------", "dispatch move", "后")
            return dispatch;
        }
        if (action == MotionEvent.ACTION_CANCEL) {
            Log.e("HHSJ", "--------父视图 dispatch cancel===")
        }
        if (action == MotionEvent.ACTION_UP) {
            Log.e("HHSJ", "--------父视图 dispatch up===")
        }
        return super.dispatchTouchEvent(ev)
    }

    private fun printTarget(prefix: String, methodName: String, timeStr: String) {
        if (!showTouchTarget) {
            return
        }
        try {
            loopPrintTarget(this, prefix, methodName, timeStr)
        } catch (e: NoSuchFieldException) {
            e.printStackTrace()
        } catch (e: IllegalAccessException) {
            e.printStackTrace()
        }
    }

    private fun loopPrintTarget(
        viewGroup: ViewGroup,
        prefix: String,
        methodName: String,
        timeStr: String
    ) {
        val viewGroupClass = ViewGroup::class.java
        val field = viewGroupClass.getDeclaredField("mFirstTouchTarget")
        field.isAccessible = true
        val target = field[viewGroup]

        if (target == null) {
            Log.e("HHSJ", "$prefix$methodName $timeStr mFirstTouchTarget = null")
        } else {
            try {
                Log.e(
                    "HHSJ",
                    "$prefix$methodName $timeStr mFirstTouchTarget = " + target.hashCode()
                )
                val clazz = target.javaClass
                val field1 = clazz.getDeclaredField("child")
                field1.isAccessible = true
                val child = field1.get(target)
                if (child != null) {
                    Log.e("HHSJ", "$prefix >>>> TouchTarget child " + child.hashCode())
                    Log.e("HHSJ", "$prefix >>>> ViewGroup child " + getChildAt(0).hashCode())
                    if (child is ViewGroup) {
                        loopPrintTarget(child, "${prefix}<", methodName, timeStr)
                    }
                } else {
                    Log.e("HHSJ", "$prefix >>>> TouchTarget child = null")
                }
                //不知道为什么，不能反射这个next属性
//                val field2 = clazz.getDeclaredField("next")
//                field2.isAccessible = true
//                val next = field2.get(target)
//                if (next != null) {
//                    //下一个节点
//                    loopPrintTarget(next, "${prefix}<", methodName, timeStr)
//                } else {
//                    Log.e("HHSJ", "$prefix >>>> TouchTarget next = null")
//                }
            } catch (e: NoSuchFieldException) {
                e.printStackTrace()
            } catch (e: IllegalAccessException) {
                e.printStackTrace()
            }
        }
    }
}